//                                                                                             
// This code is part of DOMinator extension
// @Copyright Stefano.dipaola@mindedsecurity.com
// This code is copyrighted
//
var EXPORTED_SYMBOLS=["Sinks","sinks","getSources"]
var sinks=["Setter","Sink","SPECIALOBJKEYVALCTRL","SPECIALOBJKEYSET","OBJKEYVALCTRL","OBJKEYSET","OBJKEYGET","SPECIALOBJKEYGET"];
 

var attack={XSS:"JSExecution",HPP:"Http Parameter Pollution",COOKIEINJ:"Cookie Injection",URLREDIR:"URL Redirection",FORMHIJACK:"Form Hijacking",
CSRF:"Cross Site Request Forgery"};
const DEBUG=true;
if(!DEBUG){
 dump=function(){}
}
/*
 Returns a reverted object from sources to result String.
 also adds to InfoTaint Object the parent objects retrievable 
 using _pboj.
 
*/
function getSources(obj,pobj,aa){
   if(aa==null)
    aa=[]
   if(obj==null)
    return "Object is not referenced";
   var s;
   if(pobj!=null)
    obj._pobj=pobj;
   if(obj.source){
           aa.push(obj)
           s+=' '+obj.source+' ';
  }

 if(obj.dep)
   for(var i=0,length=obj.dep.length;i<length;i++){
   aa.concat(getSources( obj.dep[i],obj ,aa))
  //s+= getSource( obj.dep[i],obj )
 }
  return aa;
 }
 
/*
  creates ---
*/
function getOpFlow(obj,lev,op,c){
  try{ 
   if(!op)
     op={}
   if(! op[obj.op])
     op[obj.op]={lev:[]};
   op[obj.op].lev.push(lev);
   if(obj.startPos>-1){
    op[obj.op].startPos=obj.startPos;
    op[obj.op].endPos=obj.endPos;
    op[obj.op].val=obj.val;
   }
   if(e[obj.op]){
     var i=c.length;
     while(i--)
       c[i]=e[obj.op](c[i]);
   }
   if(obj._pobj) 
     c= getOpFlow(obj._pobj,++lev,op,c);
   return c;
  }catch(ex){ dump("[EEEE ]"+ex+"")}
}
var e={"UNESCAPE":unescape,"DECODEURI":decodeURI,"DECODEURICOMPONENT":decodeURIComponent,
       "ESCAPE":escape,"ENCODEURI":encodeURI,"ENCODEURICOMPONENT":encodeURIComponent};

Sinks = {
 /*
 _documentWrite: {
    isExploitable:function(info){  
    var vv=getSources(info,null );
    var cc=vv.length;
    var c=['"',">","&","="];
    var f=c.slice();
    var isNotCookieOnly=false;
    while(cc--){ 
     o={};
     if(vv[cc].source!="cookie")
       isNotCookieOnly=true;
     var xx= getOpFlow(vv[cc ],0,o,f);
     var i=xx.length;
     vv[cc]['Exploitable']=0
     while(i--)
      if(xx[i]==c[i]){
       dump("siii "+xx[i]+"\n");
       vv[cc]['Exploitable']++;
      }else{
       dump("nooo "+xx[i]+" "+c[i]+"\n");
      }
    }
    return {val:isNotCookieOnly?"red":"yellow",obj:vv};
  }
 }
 , */
 /* doc.write , innerHTML etc*/
 classic:{
    ok: ["UNESCAPE","ENCODEURI","DECODEURICOMPONENT"],
    ko: ["ESCAPE"  ,"DECODEURI","DECODEURICOMPONENT"],
  isExploitable:function(info){
  try{
    dump(info.toSource()+"\n__________________________________")
    var vv=getSources(info,null );
    var cc=vv.length;
    var c=['"', ">","&","=","%0a"];
    var f=c.slice();
    var isCookieOnly=true;
    var  isProtoHostOnly=true;
    var expl=0;
    var decoded=0;
    while(cc--){ 
     o={};
     if(vv[cc].source!="location.protocol" && vv[cc].source!="location.host" && vv[cc].source!="location.hostname" )
       isProtoHostOnly=false;
     if(vv[cc].source!="cookie")
       isCookieOnly=false;
     var xx= getOpFlow(vv[cc ],0,o,f);
     var i=xx.length-1;
     dump(c[ xx.length-1] +" "+xx[xx.length-1]+" sssss\n");
     if(xx[xx.length-1]=="\n"){
       vv[cc]['Exploitable']= xx.length+1;
       vv[cc]['Decoded'] = true;
     }else{
     vv[cc]['Exploitable']=0;
     while(i--)
      if(xx[i]==c[i]){
       dump("siii "+xx[i]+"\n");
       vv[cc]['Exploitable']++;
      }else{
       dump("nooo "+xx[i]+" "+c[i]+"\n");
      }
     }
     if(vv[cc]['Exploitable'] && vv[cc].source!="cookie" && vv[cc].source!="location.protocol" && vv[cc].source!="location.host" && vv[cc].source!="location.hostname")
       expl++;
     if(vv[cc]['Decoded']){
       decoded++;
     }
    }
    dump("\n\n::::::::::::::::::::::"+vv.toSource(2)+"\n"+" _____ \n"+expl +"\n____\n")
    
    return {cookie:isCookieOnly,isExpl:expl ?true:false,isDecoded:decoded?true:false,obj:vv};
   }catch(rr){dump("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ "+rr+"\n\n\n\n\n\n")}
  }
},
 _request:{
    ok: ["UNESCAPE","ENCODEURI","DECODEURICOMPONENT"],
    ko: ["ESCAPE"  ,"DECODEURI","DECODEURICOMPONENT"],
  isExploitable:function(info){
    return true
  }
},
 _eval:{
    ok: ["UNESCAPE","ENCODEURI","DECODEURICOMPONENT"],
    ko: ["ESCAPE"  ,"DECODEURI","DECODEURICOMPONENT"],
  isExploitable:function(info){
    
     try{
    dump(info.toSource()+"\nEVALLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL\n")
    var vv=getSources(info,null );
    var cc=vv.length;
    var c=['"',"'",">","&","="];
    var f=c.slice();
    var isCookieOnly=true;
    var expl=0;
    while(cc--){ 
     o={};
     if(/*vv[cc].source!="cookie" && */vv[cc].source!="location.protocol" && vv[cc].source!="location.host" && vv[cc].source!="location.hostname" )
       isCookieOnly=false;
     var xx= getOpFlow(vv[cc ],0,o,f);
     var i=xx.length;
     vv[cc]['Exploitable']=0;
     while(i--)
      if(xx[i]==c[i]){
       dump("siii "+xx[i]+"\n");
       vv[cc]['Exploitable']++;
      }else{
       dump("nooo "+xx[i]+" "+c[i]+"\n");
      }
     if(vv[cc]['Exploitable'] && vv[cc].source!="cookie" && vv[cc].source!="location.protocol" && vv[cc].source!="location.host" && vv[cc].source!="location.hostname")
       expl++;
    }
    dump("\n\n::::::::::::::::::::::"+vv.toSource(2)+"\n"+" _____ \n"+expl +"\n____\n")
    
    return {cookie:isCookieOnly,isExpl:expl ?true:false,obj:vv};
   }catch(rr){dump("[EE] "+rr+" "+rr.lineNumber+" "+rr.fileName+"\n\n\n\n\n\n")}
 
    
  }
},
 _location:{/*assign,replace,href -- il resto e' da warning*/
    ok: ["UNESCAPE","ENCODEURI","DECODEURICOMPONENT"],
    ko: ["ESCAPE"  ,"DECODEURI","DECODEURICOMPONENT"],
  isExploitable:function(info){
     var vv=getSources(info,null);
     var cc=vv.length;
     var c=[':',";","&","="];
     var f=c.slice();
     var isCookieOnly=true;
     var expl=0;
     var isInitial=false;
     var isConcat=false;

     while(cc--){ 
      o={};
      if(vv[cc].source!="cookie" && vv[cc].source!="location.protocol" && vv[cc].source!="location.host" && vv[cc].source!="location.hostname"   )
        isCookieOnly=false;
      if(vv[cc].startPos==0)
        isInitial=true;

      var xx= getOpFlow(vv[cc ],0,o,f);
     // dump("Location :"+xx.toSource(2)+"\n")
      var i=xx.length;
      vv[cc]['Exploitable']=0;
      while(i--){
       if(xx[i]==c[i]){
        dump("location:siii "+xx[i]+"\n");
        vv[cc]['Exploitable']++;
       } else {
        dump("location:nooo "+xx[i]+" "+c[i]+"\n");
       }
      }

      var iter=Iterator(o)
      for(var pair in iter){
        if(pair[0].match(/CONCAT/))
         isConcat=true;
        if(pair[1].startPos==0)
          isInitial=true;
      }
      if(vv[cc]['Exploitable']  )
        expl++;
     }
     dump("\n\n::::::::::::::::::::::"+vv.toSource(2)+"\n"+" _____ \n"+expl +"\n____\n")

     return {cookie:isCookieOnly,isExpl:expl && (isInitial || !isConcat)?true:false,obj:vv};
  
  }
}, 
 _cookie:{
    ok: ["UNESCAPE","ENCODEURI","DECODEURICOMPONENT"],
    ko: ["ESCAPE"  ,"DECODEURI","DECODEURICOMPONENT"],
  isExploitable:function(info){dump(info+"\n");
     var vv=getSources(info,null);
     var cc=vv.length;
     var c=['"',"'"," ","<",">","&","=","%0a"];
     var f=c.slice();
     var isCookieOnly=true;
     var expl=0;
     var isInitial=false;
     var isConcat=false;
    var decoded=0;

     while(cc--){ 
      o={};
      if(vv[cc].source!="cookie" && vv[cc].source!="location.protocol" && vv[cc].source!="location.host" && vv[cc].source!="location.hostname"   )
        isCookieOnly=false;
      if(vv[cc].startPos==0)
        isInitial=true;

      var xx= getOpFlow(vv[cc ],0,o,f);
      dump("Location :"+xx.toSource(2)+"\n")
      var i=xx.length;
      if(xx[xx.length-1]=="\n"){
       vv[cc]['Exploitable']= xx.length+1;
       vv[cc]['Decoded'] = true;
      }else{
       vv[cc]['Exploitable']=0;
       while(i--){
        if(xx[i]==c[i]){
         dump("location:siii "+xx[i]+"\n");
         vv[cc]['Exploitable']++;
        } else {
         dump("location:nooo "+xx[i]+" "+c[i]+"\n");
        }
       }
      }
      var iter=Iterator(o)
      for(var pair in iter){
        if(pair[0].match(/CONCAT/))
         isConcat=true;
        if(pair[1].startPos==0)
          isInitial=true;
      }
      if(vv[cc]['Exploitable'] && vv[cc].source!="location.protocol" && vv[cc].source!="location.host" && vv[cc].source!="location.hostname" )
        expl++;
     if(vv[cc]['Decoded'] && vv[cc].source!="location.protocol" && vv[cc].source!="location.host" && vv[cc].source!="location.hostname"){
       decoded++;
     }
     }
      dump("\n\n::::::::::::::::::::::"+vv.toSource(2)+"\n"+" _____ \n"+expl +"\n____\n")

     return {cookie:isCookieOnly,isExpl:expl ?true:false,isDecoded:decoded?true:false,obj:vv};
    
  }
},
 _SinkUrl:{/* tag con url rilevanti*/
    ok: ["UNESCAPE","ENCODEURI","DECODEURICOMPONENT"],
    ko: ["ESCAPE"  ,"DECODEURI","DECODEURICOMPONENT"],
  isExploitable:function(info){
    return true
  }
},
 jQuery:{
    ok: ["UNESCAPE","ENCODEURI","DECODEURICOMPONENT"],
    ko: ["ESCAPE"  ,"DECODEURI","DECODEURICOMPONENT"],
  isExploitable:function(info){
    return true
  }
}
 
}
